/*
 * @Author: 0x9DEFA478
 * @Date: 2022-06-21 21:25:43
 * @LastEditTime: 2022-06-23 23:14:17
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#ifndef __IP_SDMMC_SD_H_
#define __IP_SDMMC_SD_H_
#include "sdmmc.h"




/**
 * 响应结果枚举
 */

#define vIP_SDMMC_SD_CmdRespondDone_Result_Error                  -1
#define vIP_SDMMC_SD_CmdRespondDone_Result_Ok                     0
#define vIP_SDMMC_SD_CmdRespondDone_Result_Timeout                1

typedef struct{
  int Result;                          //响应结果
  struct{
    unsigned char Command;             //响应的指令 低位对齐
    unsigned int CardStatus[4];        //卡状态 小端高位对齐
  }Respond;
}IP_SDMMC_SD_RespondDoneParam;


/**
 * 响应类型枚举
 */

#define vIP_SDMMC_SD_CmdParam_RespondType_None                    0
#define vIP_SDMMC_SD_CmdParam_RespondType_Short                   1
#define vIP_SDMMC_SD_CmdParam_RespondType_Long                    2

typedef struct{

  struct{
    unsigned char Command;             //命令
    unsigned int Argument;             //参数
  }Send;

  struct{
    int Type;                          //将要响应的类型
  }Respond;

  struct{
    void* v;                           //回调使用的参数
    void (*SendDone)(void*);           //命令发送完成回调
    void (*RespondDone)(void*,IP_SDMMC_SD_RespondDoneParam*);//接收响应完成回调 (回调使用的参数,回调参数)
  }Callback;
}IP_SDMMC_SD_CmdParam;


/**
 * 数据传输结果枚举
 */

#define vIP_SDMMC_SD_DataDone_Result_Error                        -1
#define vIP_SDMMC_SD_DataDone_Result_Ok                           0
#define vIP_SDMMC_SD_DataDone_Result_Timeout                      1

typedef struct{
  struct{
    int IsTransmit;                    //数据传输方向 0:接收 其他:发送
    int BlockSize;                     //块大小 如果使用流传输 设置此段为非正数
    int Length;                        //数据长度 如果为块传输, 此段为BlockSize的倍数, 单位:字节
    void* Buffer;                      //要发送/容纳接收数据的缓存 需要4字节对齐
    unsigned int TimeoutClk;           //数据接收超时CLK数
  }Data;
  struct{
    void* v;                           //回调使用的参数
    void (*Done)(void*,int);           //传输完成回调 (回调使用的参数,传输结果)
  }Callback;
}IP_SDMMC_SD_DataParam;




//使能节能模式
#define vIP_SDMMC_SD_Feature_PowerSave                            SDMMC_CLKCR_PWRSAV
//在SDIOCLK的下降沿产生SDIO_CK
#define vIP_SDMMC_SD_Feature_NEGEDG_Fall                          SDMMC_CLKCR_NEGEDGE
//启用硬件流控
#define vIP_SDMMC_SD_Feature_HardwareFlowControl                  SDMMC_CLKCR_HWFC_EN




#define vIP_SDMMC_SD_ICR_ALL                                      0x1FE0FFFU




//获取SDMMC_SD实例
#define cIP_SDMMC_SD_SDMMC(ip_sdmmc_sd)   ((ip_sdmmc_sd)->Instance.Instance)




typedef struct{
  struct{
    SDMMC_TypeDef* Instance;
  }Instance;

  int CLKDIV;
  int BusWidth;
  int BlockSize;

  volatile int CommandIsBusy;//命令传输是否忙
  volatile int DataIsBusy;//数据传输是否忙

  volatile int IsOdd;
  void* volatile LastBuffer;
  volatile int LastLength;
  
  IP_SDMMC_SD_CmdParam volatile CmdParam;
  IP_SDMMC_SD_DataParam volatile DataParam;

}IP_SDMMC_SD;




/**
 * @brief 初始化 IP_SDMMC_SD
 * @param ip_sdmmc_sd 空的IP_SDMMC_SD对象(已分配内存的)
 * @param _sdmmc sdmmc句柄
 * @param Feature 一些特性信息 0为默认值
 * @param SetIrqCallback 设置中断回调方法
 * @param TransferBuffer 传输缓存
 * @param SetIrqCallback 传输缓存大小 必须为2的倍数 单位:4字节
 * @return 无
 */
void IP_SDMMC_SD_Init(IP_SDMMC_SD* ip_sdmmc_sd,SDMMC_TypeDef* _sdmmc,unsigned int Feature,void (*SetIrqCallback)(void (*)(void*),void*)
  ,unsigned int* TransferBuffer,int TransferBufferSize);

/**
 * @brief 设置sdmmc_ker_ck到SDMMC_CK的分频 在SDMMC不进行通信时使用
 * @param ip_sdmmc_sd IP_SDMMC_SD对象
 * @param CLKDIV 分频 1 2 4 6 ... 2046 (大于1的分频值只能为2的倍数并且小于等于2046)
 * @return 成功:实际分频值 非正数:失败
 */
int IP_SDMMC_SD_SetCLKDIV(IP_SDMMC_SD* ip_sdmmc_sd,int CLKDIV);

/**
 * @brief 设置位宽 在SDMMC不进行通信时使用
 * @param ip_sdmmc_sd IP_SDMMC_SD对象
 * @param BusWidth 位宽 1, 4, 8, 可选
 * @return 0:成功 其他:失败
 */
int IP_SDMMC_SD_SetBusWidth(IP_SDMMC_SD* ip_sdmmc_sd,int BusWidth);

/**
 * @brief 设置时钟状态
 * @param ip_sdmmc_sd IP_SDMMC_SD对象
 * @param IsOn 0:掉电 其他:提供时钟
 * @return 无
 */
void IP_SDMMC_SD_SetPower(IP_SDMMC_SD* ip_sdmmc_sd,int IsOn);




/**
 * @brief 进行SDMMC指令响应通信
 * @param ip_sdmmc_sd IP_SDMMC_SD对象
 * @param Param 通信参数
 * @return 0:通信发起成功 其他:通信发起失败
 */
int IP_SDMMC_SD_CmdCommunication(IP_SDMMC_SD* ip_sdmmc_sd,IP_SDMMC_SD_CmdParam* Param);

/**
 * @brief 进行SDMMC数据通信
 * @param ip_sdmmc_sd IP_SDMMC_SD对象
 * @param Param 通信参数
 * @return 0:通信发起成功 其他:通信发起失败
 */
int IP_SDMMC_SD_DataCommunication(IP_SDMMC_SD* ip_sdmmc_sd,IP_SDMMC_SD_DataParam* Param);

/**
 * @brief 进行SDMMC指令响应并传输数据通信 Cmd与Data同时触发
 * @param ip_sdmmc_sd IP_SDMMC_SD对象
 * @param CmdParam 命令通信参数
 * @param DataParam 数据通信参数
 * @return 0:通信发起成功 其他:通信发起失败
 */
int IP_SDMMC_SD_CmdDataCommunication(IP_SDMMC_SD* ip_sdmmc_sd,IP_SDMMC_SD_CmdParam* CmdParam,IP_SDMMC_SD_DataParam* DataParam);




#endif //__IP_SDMMC_SD_H_
